#include <stdint.h>
#include <stdio.h>

#define CABAC_SIZE_BITS 8
#define FIX8(f) ((int)(f*(1<<8)+.5))

static uint8_t cabac_transition_5ones[128];
static uint16_t cabac_size_5ones[128];

const uint8_t x264_cabac_transition[128][2] =
{
    {  0,   0}, {  1,   1}, {  2,  50}, { 51,   3}, {  2,  50}, { 51,   3}, {  4,  52}, { 53,   5},
    {  6,  52}, { 53,   7}, {  8,  52}, { 53,   9}, { 10,  54}, { 55,  11}, { 12,  54}, { 55,  13},
    { 14,  54}, { 55,  15}, { 16,  56}, { 57,  17}, { 18,  56}, { 57,  19}, { 20,  56}, { 57,  21},
    { 22,  58}, { 59,  23}, { 24,  58}, { 59,  25}, { 26,  60}, { 61,  27}, { 28,  60}, { 61,  29},
    { 30,  60}, { 61,  31}, { 32,  62}, { 63,  33}, { 34,  62}, { 63,  35}, { 36,  64}, { 65,  37},
    { 38,  66}, { 67,  39}, { 40,  66}, { 67,  41}, { 42,  66}, { 67,  43}, { 44,  68}, { 69,  45},
    { 46,  68}, { 69,  47}, { 48,  70}, { 71,  49}, { 50,  72}, { 73,  51}, { 52,  72}, { 73,  53},
    { 54,  74}, { 75,  55}, { 56,  74}, { 75,  57}, { 58,  76}, { 77,  59}, { 60,  78}, { 79,  61},
    { 62,  78}, { 79,  63}, { 64,  80}, { 81,  65}, { 66,  82}, { 83,  67}, { 68,  82}, { 83,  69},
    { 70,  84}, { 85,  71}, { 72,  84}, { 85,  73}, { 74,  88}, { 89,  75}, { 76,  88}, { 89,  77},
    { 78,  90}, { 91,  79}, { 80,  90}, { 91,  81}, { 82,  94}, { 95,  83}, { 84,  94}, { 95,  85},
    { 86,  96}, { 97,  87}, { 88,  96}, { 97,  89}, { 90, 100}, {101,  91}, { 92, 100}, {101,  93},
    { 94, 102}, {103,  95}, { 96, 104}, {105,  97}, { 98, 104}, {105,  99}, {100, 108}, {109, 101},
    {102, 108}, {109, 103}, {104, 110}, {111, 105}, {106, 112}, {113, 107}, {108, 114}, {115, 109},
    {110, 116}, {117, 111}, {112, 118}, {119, 113}, {114, 118}, {119, 115}, {116, 122}, {123, 117},
    {118, 122}, {123, 119}, {120, 124}, {125, 121}, {122, 126}, {127, 123}, {124, 127}, {126, 125}
};

const uint16_t x264_cabac_entropy[128] =
{
    FIX8(0.0273), FIX8(5.7370), FIX8(0.0288), FIX8(5.6618),
    FIX8(0.0303), FIX8(5.5866), FIX8(0.0320), FIX8(5.5114),
    FIX8(0.0337), FIX8(5.4362), FIX8(0.0355), FIX8(5.3610),
    FIX8(0.0375), FIX8(5.2859), FIX8(0.0395), FIX8(5.2106),
    FIX8(0.0416), FIX8(5.1354), FIX8(0.0439), FIX8(5.0602),
    FIX8(0.0463), FIX8(4.9851), FIX8(0.0488), FIX8(4.9099),
    FIX8(0.0515), FIX8(4.8347), FIX8(0.0543), FIX8(4.7595),
    FIX8(0.0572), FIX8(4.6843), FIX8(0.0604), FIX8(4.6091),
    FIX8(0.0637), FIX8(4.5339), FIX8(0.0671), FIX8(4.4588),
    FIX8(0.0708), FIX8(4.3836), FIX8(0.0747), FIX8(4.3083),
    FIX8(0.0788), FIX8(4.2332), FIX8(0.0832), FIX8(4.1580),
    FIX8(0.0878), FIX8(4.0828), FIX8(0.0926), FIX8(4.0076),
    FIX8(0.0977), FIX8(3.9324), FIX8(0.1032), FIX8(3.8572),
    FIX8(0.1089), FIX8(3.7820), FIX8(0.1149), FIX8(3.7068),
    FIX8(0.1214), FIX8(3.6316), FIX8(0.1282), FIX8(3.5565),
    FIX8(0.1353), FIX8(3.4813), FIX8(0.1429), FIX8(3.4061),
    FIX8(0.1510), FIX8(3.3309), FIX8(0.1596), FIX8(3.2557),
    FIX8(0.1686), FIX8(3.1805), FIX8(0.1782), FIX8(3.1053),
    FIX8(0.1884), FIX8(3.0301), FIX8(0.1992), FIX8(2.9549),
    FIX8(0.2107), FIX8(2.8797), FIX8(0.2229), FIX8(2.8046),
    FIX8(0.2358), FIX8(2.7294), FIX8(0.2496), FIX8(2.6542),
    FIX8(0.2642), FIX8(2.5790), FIX8(0.2798), FIX8(2.5038),
    FIX8(0.2964), FIX8(2.4286), FIX8(0.3142), FIX8(2.3534),
    FIX8(0.3331), FIX8(2.2782), FIX8(0.3532), FIX8(2.2030),
    FIX8(0.3748), FIX8(2.1278), FIX8(0.3979), FIX8(2.0527),
    FIX8(0.4226), FIX8(1.9775), FIX8(0.4491), FIX8(1.9023),
    FIX8(0.4776), FIX8(1.8271), FIX8(0.5082), FIX8(1.7519),
    FIX8(0.5412), FIX8(1.6767), FIX8(0.5768), FIX8(1.6015),
    FIX8(0.6152), FIX8(1.5263), FIX8(0.6568), FIX8(1.4511),
    FIX8(0.7020), FIX8(1.3759), FIX8(0.7513), FIX8(1.3008),
    FIX8(0.8050), FIX8(1.2256), FIX8(0.8638), FIX8(1.1504),
    FIX8(0.9285), FIX8(1.0752), FIX8(1.0000), FIX8(1.0000)
};

static int x264_cabac_size_decision2( uint8_t *state, long b )
{
    int i_state = *state;
    *state = x264_cabac_transition[i_state][b];
    return x264_cabac_entropy[i_state^b];
}

int main() {
    for( int i_ctx = 0; i_ctx < 128; i_ctx++ )
    {
        int f8_bits = 0;
        uint8_t ctx = i_ctx;

        for( int i = 0; i < 5; i++ )
            f8_bits += x264_cabac_size_decision2( &ctx, 1 );
        f8_bits += 1 << CABAC_SIZE_BITS; //sign

        cabac_size_5ones[i_ctx] = f8_bits;
        cabac_transition_5ones[i_ctx] = ctx;
    }

    printf("static const uint8_t cabac_transition_5ones[128] = {");
    for (int i=0; i < 128; i++) {
        if (i % 16 == 0)
            printf("\n");
        printf(" %3d,", cabac_transition_5ones[i]);
    }
    printf("\n};\n\n");

    printf("static const uint16_t cabac_size_5ones[128] = {");
    for (int i=0; i < 128; i++) {
        if (i % 8 == 0)
            printf("\n");
        printf(" %5d,", cabac_size_5ones[i]);
    }
    printf("\n};\n\n");

    return 0;
}

